#include "timer.h"

vector<Timer *> Timer::_timers;
u32 Timer::_next_id = 1;



Timer::Timer()
{
	//ctor
	_state = STATE_NONINIT;
	_flag_call = 0;
	_ID = _next_id;
	_next_id ++;
	registerThisTimer();

}

i32 Timer::init()
{
	_state = STATE_NONINIT;
	_flag_call = 0;
	_ID = _next_id;
	_next_id ++;
	return 1;
}

Timer::~Timer()
{
	unregisterThisTimer();
}

i32 Timer::start()
{
	_ticks = SDL_GetTicks();
	_state = STATE_RUNNING;
	_counted = 0;
	return 1;
}

i32 Timer::pause()
{
	if ( _state == STATE_RUNNING )
	{
		_counted = SDL_GetTicks() - _ticks;
		_ticks = SDL_GetTicks();
		_state = STATE_PAUSED;
		return 1;
	}

	if ( _state == STATE_NONINIT )
	{
		_ticks = SDL_GetTicks();
		_counted = 0;
		_state = STATE_PAUSED;
		return 1;
	}

	// if its already paused, then do nothing.
	return 1;
}

i32 Timer::unpause()
{
	if ( _state == STATE_NONINIT )
	{
		_counted = 0;
	}

	_ticks = SDL_GetTicks();

	if ( _flag_call )
	{
		_next_call = SDL_GetTicks() + _interval - _counted;
	}

	_state = STATE_RUNNING;
	return 1;
}

i32 Timer::reset()
{
	_ticks = SDL_GetTicks();
	_counted = 0;

	if ( _flag_call )
	{
		_next_call = SDL_GetTicks() + _interval;
	}

	return 1;
}

i32 Timer::doPeriodicaly ( i32 time_ms, callbackV1 call )
{
	_call = call;
	_interval = time_ms;
	_next_call = time_ms + SDL_GetTicks();
	_flag_call = 1;
	_type_of_call = TYP_PERIOD;
	return 1;
}

i32 Timer::doOnce ( i32 time_ms, callbackV1 call )
{
	_call = call;
	_interval = time_ms;
	_next_call = time_ms + SDL_GetTicks();
	_flag_call = 1;
	_type_of_call = TYP_ONCE;
	return 1;
}

i32 Timer::getTime()
{
	if ( _state == STATE_RUNNING )
	{
		_counted += SDL_GetTicks() - _ticks;
		_ticks = SDL_GetTicks();
	}

	return _counted;
}

i32 Timer::registerThisTimer()
{
	_timers.push_back ( this );
	return 1;
}

i32 Timer::unregisterThisTimer()
{
	for ( u32 c = 0; c < _timers.size(); c++ )
	{
		if ( _timers[c]->_ID == _ID )
		{
			_timers.erase ( _timers.begin() + c );
			return 1;
		}
	}

	LOGP2 ( "WARN: Timer : Can't unregister timer ID[%d]", _ID );
	return 0;
}

i32 Timer::checkAndRun()
{
	i32 now = SDL_GetTicks();

	for ( u32 c = 0; c < _timers.size(); c++ )
	{
		Timer *t = _timers[c];

		if ( ( t->_flag_call ) && ( t->_state == STATE_RUNNING ) )
		{
			if ( t->_next_call <= now )
			{
				if ( t->_call )
				{
					t->_call();    // execute
				}

				if ( t->_type_of_call == TYP_ONCE )
				{
				    t->_state = STATE_NONINIT;
				}
				if ( t->_type_of_call == TYP_PERIOD)
                {
                    t->_next_call = now + t->_interval;
                }
			}
		}
	}
	return 1;
}

